package com.eeds.rabbit;

import com.eeds.common.constant.RabbitConstants;
import com.eeds.json.GsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnCallback;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
/**
 * @author Flying
 * @Description
 * @date 16:40 2018-10-25
 **/
@Component
@Slf4j
@ConditionalOnProperty(prefix = "rabbitmq",value = {"enable"},havingValue = "true")
public class RabbitSender implements RabbitTemplate.ConfirmCallback, ReturnCallback {


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            if(log.isDebugEnabled()){
                log.debug( "消息发送成功:{}", correlationData);
            }
        } else {
            if(log.isDebugEnabled()){
                log.error( "消息发送失败:{}", cause);
            }
        }

    }

    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        if(log.isErrorEnabled()) {
            log.error("{} 发送失败", message.getMessageProperties().getCorrelationIdString());
        }
    }




    /**
     * 发送消息
     * @param key
     * @param msg
     */
    public void convertAndSendJson(String key,Object msg){
        final String messageJson = GsonUtil.GsonString(msg);
        rabbitTemplate.convertAndSend(RabbitConstants.REFUND_EXCHANGE,key, messageJson,(message)->{
                        MessageProperties mp = message.getMessageProperties();
                        // rabbitmq会在amqp消息头中把原有的包名带进去。
                        mp.setHeader("__TypeId__",
                                String.class.getName());
                        return message;
                });
    }

    /**
     * 发送消息
     * @param key
     * @param msg
     */
    public void convertAndSendJson(String exchange, String key, Object msg){
        final String messageJson = GsonUtil.GsonString(msg);
        rabbitTemplate.convertAndSend(exchange, key, messageJson,(message)->{
            MessageProperties mp = message.getMessageProperties();
            // rabbitmq会在amqp消息头中把原有的包名带进去。
            mp.setHeader("__TypeId__",
                    String.class.getName());
            return message;
        });
    }


    /**
     * 发送消息 需要传入交换机
     * @param key
     * @param msg
     */
    public void convertAndSend( String key,final Object msg){
        rabbitTemplate.convertAndSend(RabbitConstants.REFUND_EXCHANGE,key, msg,(message)->{
                        MessageProperties mp = message.getMessageProperties();
                        // rabbitmq会在amqp消息头中把原有的包名带进去。
                        mp.setHeader("__TypeId__",
                                msg.getClass().getName());
                        return message;
                });
    }


    /**
     * 发送延迟消息
     * 默认延迟 10分钟
     * @param key
     * @param msg
     */
    public void convertAndSendDelay(String exchange,  String key,final Object msg){
        this.convertAndSendDelay(exchange, key,msg,null);
    }

    /**
     * 发送消息 需要传入交换机和延迟时间
     * 默认延迟 10分钟
     * @param key
     * @param msg
     */
    public void convertAndSendDelay(String exchange,  String key,final Object msg, final String seconds){
        rabbitTemplate.convertAndSend(exchange, key, msg,(message)->{
                        MessageProperties mp = message.getMessageProperties();
                        // rabbitmq会在amqp消息头中把原有的包名带进去。
                        mp.setHeader("__TypeId__",
                                msg.getClass().getName());
                        mp.setExpiration("60000");
                        if(seconds != null){
                            mp.setExpiration(seconds);
                        }
                        return message;
                });
    }

    /**
     * 发送延迟消息
     * 默认延迟 10分钟
     * @param key
     * @param msg
     */
    public void convertAndSendJsonDelay(String exchange, String key,final Object msg){
        this.convertAndSendJsonDelay(exchange, key,msg,null);
    }

    /**
     * 发送消息 需要传入交换机和延迟时间
     * 默认延迟 10分钟
     * @param key
     * @param msg
     */
    public void convertAndSendJsonDelay(String exchange, String key, Object msg, final String seconds){
        final String messageJson = GsonUtil.GsonString(msg);
        rabbitTemplate.convertAndSend(exchange, key, messageJson,(message)->{
            MessageProperties mp = message.getMessageProperties();
            // rabbitmq会在amqp消息头中把原有的包名带进去。
            mp.setHeader("__TypeId__",
                    String.class.getName());
            mp.setExpiration("60000");
            if(seconds != null){
                mp.setExpiration(seconds);
            }
            return message;
        });
    }
}
